package graphics;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.util.vector.Vector3f;


public class Camera3D {
	
    public Vector3f rotation = new Vector3f(0, 0, 0);
    public  Vector3f position = new Vector3f(0, 0, 0);

    private final int MAX_LOOK_DOWN = -85;
    private final int MAX_LOOK_UP = 85;
    
    private int mouseSpeed = 2;
    private int walkingSpeed = 10;
    private long lastFrame;
	
	public Camera3D() {
		// TODO Auto-generated constructor stub
	}
	
	public void update(){
        
		mouseStuff();
        keyboardStuff();
	}
	
	private void mouseStuff()
	{
        float mouseDX = Mouse.getDX() * mouseSpeed * 0.16f;
        float mouseDY = Mouse.getDY() * mouseSpeed * 0.16f;
        if (rotation.y + mouseDX >= 360) {
            rotation.y = rotation.y + mouseDX - 360;
        } else if (rotation.y + mouseDX < 0) {
            rotation.y = 360 - rotation.y + mouseDX;
        } else {
            rotation.y += mouseDX;
        }
        if (rotation.x - mouseDY >= MAX_LOOK_DOWN && rotation.x - mouseDY <= MAX_LOOK_UP) {
            rotation.x += -mouseDY;
        } else if (rotation.x - mouseDY < MAX_LOOK_DOWN) {
            rotation.x = MAX_LOOK_DOWN;
        } else if (rotation.x - mouseDY > MAX_LOOK_UP) {
            rotation.x = MAX_LOOK_UP;
        }
		
	}

	private void keyboardStuff() {

        int delta = getDelta();
		boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_UP) || Keyboard.isKeyDown(Keyboard.KEY_W);
        boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_DOWN) || Keyboard.isKeyDown(Keyboard.KEY_S);
        boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_A);
        boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_RIGHT) || Keyboard.isKeyDown(Keyboard.KEY_D);
        boolean flyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
        boolean flyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
        boolean moveFaster = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL);
        boolean moveSlower = Keyboard.isKeyDown(Keyboard.KEY_TAB);

        if (moveFaster && !moveSlower) {
            walkingSpeed *= 4f;
        }
        if (moveSlower && !moveFaster) {
            walkingSpeed /= 10f;
        }

        if (keyUp && keyRight && !keyLeft && !keyDown) {
            float angle = rotation.y + 45;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyUp && keyLeft && !keyRight && !keyDown) {
            float angle = rotation.y - 45;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyUp && !keyLeft && !keyRight && !keyDown) {
            float angle = rotation.y;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyDown && keyLeft && !keyRight && !keyUp) {
            float angle = rotation.y - 135;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyDown && keyRight && !keyLeft && !keyUp) {
            float angle = rotation.y + 135;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyDown && !keyUp && !keyLeft && !keyRight) {
            float angle = rotation.y;
            Vector3f newPosition = new Vector3f(position);
            float schuine = -(walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyLeft && !keyRight && !keyUp && !keyDown) {
            float angle = rotation.y - 90;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (keyRight && !keyLeft && !keyUp && !keyDown) {
            float angle = rotation.y + 90;
            Vector3f newPosition = new Vector3f(position);
            float schuine = (walkingSpeed * 0.0002f) * delta;
            float aanliggende = schuine * (float) Math.cos(Math.toRadians(angle));
            float overstaande = (float) (Math.sin(Math.toRadians(angle)) * schuine);
            newPosition.z += aanliggende;
            newPosition.x -= overstaande;
            position.z = newPosition.z;
            position.x = newPosition.x;
        }
        if (flyUp && !flyDown) {
            double newPositionY = (walkingSpeed * 0.0002) * delta;
            position.y -= newPositionY;
        }
        if (flyDown && !flyUp) {
            double newPositionY = (walkingSpeed * 0.0002) * delta;
            position.y += newPositionY;
        }
        if (moveFaster && !moveSlower) {
            walkingSpeed /= 4f;
        }
        if (moveSlower && !moveFaster) {
            walkingSpeed *= 10f;
        }
        while (Mouse.next()) {
            if (Mouse.isButtonDown(0)) {
                Mouse.setGrabbed(true);
            }
            if (Mouse.isButtonDown(1)) {
                Mouse.setGrabbed(false);
            }

        }
        while (Keyboard.next()) {
            if (Keyboard.isKeyDown(Keyboard.KEY_C)) {
                position = new Vector3f(0, 0, 0);
                rotation = new Vector3f(0, 0, 0);
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_O)) {
                mouseSpeed += 1;
                System.out.println("Mouse speed changed to " + mouseSpeed + ".");
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_L)) {
                if (mouseSpeed - 1 > 0) {
                    mouseSpeed -= 1;
                    System.out.println("Mouse speed changed to " + mouseSpeed + ".");
                }
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
                System.out.println("Walking speed changed to " + walkingSpeed + ".");
                walkingSpeed += 1;
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_Z)) {
                System.out.println("Walking speed changed to " + walkingSpeed + ".");
                walkingSpeed -= 1;
            }
        }
	}

	private int getDelta() {
		// 
		long currentTime = getTime();
        int delta = (int) (currentTime - lastFrame);
        lastFrame = getTime();
        return delta;
	}

    private long getTime() {
        return (Sys.getTime() * 1000) / Sys.getTimerResolution();
    }
}
